home *** CD-ROM | disk | FTP | other *** search
/ Video Toaster 4.0 / Video Toaster v4.0.iso / arexx / modeler / pointspread.lwm < prev    next >
Text File  |  1993-12-13  |  5KB  |  192 lines

  1. /* PointSpread.lwm -- Distribute particles in Modeler space. CMD: Point Distributions
  2.  * By Arnie Cachelin © 1992, 1993 NewTek Inc. */
  3.  
  4. libadd = addlib("LWModelerARexx.port",0)
  5. signal on error
  6. signal on syntax
  7.  
  8. Fn.0 = dist_RadialLinInc
  9. Fn.1 = dist_RadialExpInc
  10. Fn.2 = dist_RadialLinDec
  11. Fn.3 = dist_RadialExpDec
  12. Fn.4 = dist_Const
  13.  
  14. FnList.1='Linear'
  15. FnList.2='Exponential'
  16. FnList.3='Constant'
  17. FnList.4='Custom'
  18. CustFn=4
  19. ufunc='sin(r*r)'
  20. FList= FnList.1 FnList.2 FnList.3 FnList.4
  21. RMax=1.0
  22. rx=1; ry=1; rz=1
  23. dist=1
  24. shape=1
  25. rate=1
  26. grad=2
  27. points=100
  28. sysnam = 'Random Point Distribution'
  29. filnam = 'ENV:PointSpread.state'
  30. version = 'PointSpread v1.1'
  31. check=1
  32.  
  33. RexxMathLib = "rexxmathlib.library"
  34. Modeler= "LWModelerARexx.port"
  35. L=SHOW('Libraries')
  36. IF POS("LWModelerARexx.port" ,L ) = 0 THEN ADDLIB("LWModelerARexx.port",0)
  37. call addlib "rexxsupport.library", 0, -30, 0
  38. IF POS(RexxMathLib ,L) = 0 THEN check=ADDLIB(RexxMathLib , 0 , -30 , 0)
  39. if ~check then do
  40.   call notify(1,"!Can't find rexxmathlib.library")
  41.   exit
  42.   end
  43.  
  44. if (exists(filnam)) then do
  45.     if (~open(state, filnam, 'R')) then break
  46.     if (readln(state) ~= version) then break
  47.     parse value readln(state) with points dist shape grad rate.
  48.     parse value readln(state) with rx ry rz
  49.     ufunc = readln(state)
  50.     call close state
  51. end
  52.  
  53. Pi=3.14159265358
  54. DegreesPerRadian= 180/pi
  55. call randu(time('s'))  /* Seed random number generator */
  56.  
  57. call req_begin sysnam
  58.  
  59. id_N   = req_addcontrol("Number of Points", 'n', 1)
  60. id_rad = req_addcontrol("Radius", 'v', 1)
  61. id_Shape=req_addcontrol("Shape", 'CH','Round Square')
  62. id_IncDec = req_addcontrol("Falloff Towards", 'CH','Center Edges')
  63. id_Rate = req_addcontrol("Steepness", 'n')
  64. id_Dist = req_addcontrol("Density Distribution", 'CH',FList)
  65. id_fun = req_addcontrol("Custom Probability (0-1)", 's', 35)
  66.  
  67. call req_setval id_Dist,dist
  68. call req_setval id_rad,rx ry rz,RMax
  69. call req_setval id_N,points
  70. call req_setval id_Rate,rate
  71. call req_setval id_IncDec,grad
  72. call req_setval id_fun, ufunc
  73. call req_setval id_Shape, shape
  74.  
  75. if (~req_post()) then do
  76.     call req_end
  77.     exit
  78. end
  79.  
  80. parse value req_getval(id_rad) with rx ry rz
  81. RMax =(rx+ry+rz)/3
  82. shape = req_getval(id_shape)
  83. points = abs(req_getval(id_N)) % 1
  84. Rate = req_getval(id_Rate)
  85. Grad = 2*(req_getval(id_IncDec)-1)
  86. fnid = req_getval(id_Dist)
  87. i=fnid-1+Grad
  88. if fnid=CustFn then do
  89.   func = req_getval(id_fun)
  90.   ufunc=func
  91.   end
  92. else func = Fn.i'(r)'
  93. if fn=CustFn-1 then func ='1'
  94.  
  95. if (open(state, filnam, 'W')) then do
  96.     call writeln state, version
  97.     call writeln state, points fnid shape grad rate.
  98.     call writeln state, rx ry rz
  99.     call writeln state, ufunc
  100.     call close state
  101. end
  102.  
  103. call req_end
  104.  
  105. call add_begin
  106. call meter_begin points+1, "Generating "points" Points", FnList.fnid" Distribution."
  107.  
  108. N=0
  109. do i=1 to points
  110.   N=N+1
  111.   if(shape=1) then do
  112.     x=(2*randu()-1)*rx
  113.     y=(2*randu()-1)*ry
  114.     z=(2*randu()-1)*rz
  115.     r=Sphere_R(x,y,z)
  116.     interpret 'P='func
  117.     if(randu()<P) then do
  118.       call add_point x y z
  119.       call add_polygon i
  120.       call meter_step
  121.       end
  122.     else i=i-1
  123.     end
  124.   else do
  125.     x=(2*randu()-1)*rx
  126.     r=x
  127.     interpret 'P1='func
  128.     y=(2*randu()-1)*ry
  129.     r=y
  130.     interpret 'P2='func
  131.     z=(2*randu()-1)*rz
  132.     r=z
  133.     interpret 'P3='func
  134.     P=(P1+P2+P3)/3
  135.     if(randu()<P) then do
  136.       call add_point x y z
  137.       call add_polygon i
  138.       call meter_step
  139.       end
  140.     else i=i-1
  141.     end
  142. end
  143. call add_end
  144. call notify(1,'!'version,"@Drew "i-1" points out of "N)
  145.  
  146. exit
  147.  
  148. syntax:
  149. error:
  150.   call end_all
  151.   if (libadd) then call remlib("LWModelerARexx.port")
  152.     t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
  153.     exit
  154.  
  155. /* These functions return a probability based on position for various
  156.    particle distributions.  This probability is used, Monte Carlo style,
  157.    to filter random positions generated above.  This is an inefficient way
  158.    to do this, but it should be very general, and computers are meant to do
  159.    boring, repetitive tasks with brute force... aren't they?
  160. */
  161.  
  162. dist_Const:  PROCEDURE EXPOSE RMax
  163.   arg r
  164.   if(r>RMax) then return 0
  165.   else return 1
  166.  
  167. dist_RadialLinDec:  PROCEDURE EXPOSE RMax
  168.   arg r
  169.   if(r>RMax) then return 0
  170.   else return (RMax-r)/RMax
  171.  
  172. dist_RadialLinInc:  PROCEDURE EXPOSE RMax
  173.   arg r
  174.   if(r>RMax) then return 0
  175.   else return r/RMax
  176.  
  177. dist_RadialExpDec:  PROCEDURE EXPOSE Rate RMax
  178.   arg r
  179.   if(r>RMax) then return 0
  180.   else return exp(-Rate*r/RMax)
  181.  
  182. dist_RadialExpInc:  PROCEDURE EXPOSE Rate RMax
  183.   arg x, y, z
  184.   if(r>RMax) then return 0
  185.   else return exp(-Rate*(r-RMax)/RMax)
  186.  
  187. /* Return R in Spherical coordinate system */
  188.  
  189. Sphere_R: PROCEDURE
  190.     arg x, y, z
  191.   return sqrt(x*x+y*y+z*z)
  192.